﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Interactivity;
using nRoute.Components.TypeConverters;
#if (WINRT)
using Windows.UI.Xaml;
using nRoute.Behaviors.Interactivity;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Data;
using System.Reflection;
#else
using System.Windows.Markup;
#endif

namespace nRoute.Behaviors
{
#if (WINRT)
    [ContentProperty(Name = "Value")]
#else
    [ContentProperty("Value")]
#endif
    public class TargetedSetPropertyAction
#if (WINRT)
        : TargetedTriggerAction<FrameworkElement>
#else
        : TargetedTriggerAction<DependencyObject>
#endif
    {
        public static readonly DependencyProperty PropertyNameProperty =
            DependencyProperty.Register("PropertyName", typeof(string), typeof(TargetedSetPropertyAction),
            new PropertyMetadata(Utilities.Compatability.DP_UNSET_VALUE));

        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(object), typeof(TargetedSetPropertyAction),
            new PropertyMetadata(Utilities.Compatability.DP_UNSET_VALUE));

#region Properties

        // it might be possible to de
        //public Binding TargetBinding { get; set; }

        [Category("Common Properties")]
        public string PropertyName
        {
            get { return Convert.ToString(GetValue(PropertyNameProperty)); }
            set { SetValue(PropertyNameProperty, value); }
        }

        [Category("Common Properties")]
//#if WP7
//        [TypeConverter(typeof(nRoute.Components.TypeConverters.ConvertFromStringConverter))]
//#endif
        [CustomPropertyValueEditor(CustomPropertyValueEditor.PropertyBinding)]
        public Object Value
        {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

#endregion

#region Trigger Related

        protected override void Invoke(object parameter)
        {
            if (string.IsNullOrEmpty(this.PropertyName) || this.Target == null) return;
            
#if (WINRT)
            // we set the value
            var _propertyInfo = this.Target.GetType().GetTypeInfo().GetDeclaredProperty(this.PropertyName);
            if (_propertyInfo == null || !_propertyInfo.CanWrite) return;

            // else we convert and set the value - note no type converter
            var _value = ConverterHelper.ConvertToType(Value, _propertyInfo.PropertyType);
            _propertyInfo.SetValue(this.Target, _value);
#else
            // we set the value
            var _propertyInfo = this.Target.GetType().GetProperty(this.PropertyName);
            if (_propertyInfo == null || !_propertyInfo.CanWrite) return;

            // else we convert and set the value
            var _value = ConverterHelper.ConvertToType(Value, _propertyInfo.PropertyType);
            _propertyInfo.SetValue(this.Target, _value, null);
#endif

        }

#endregion

    }
}
